<!--
Copyright 2014 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<link rel="import" href="../ct-failure-group.html">

<script>
(function () {

var assert = chai.assert;

describe('ct-sheriff-failure-group', function() {

  beforeEach(function() {
    localStorage.removeItem('CTFailureGroupAnnotations');
  });

  var key = 0;
  function newFailureWithAnnotation(annotation, isTreeCloser) {
    return new CTStepFailure('step', 'reason', [
      {key: String(key++), annotation: annotation, isTreeCloser: isTreeCloser}
    ]);
  }

  describe('category', function() {
    it('should be "default" by default', function() {
      var group = new CTFailureGroup('', new CTStepFailureGroupData([]));
      assert.equal(group.category, 'default');
    });

    it('should be "snoozed" when snoozed', function() {
      var group = new CTFailureGroup('', new CTStepFailureGroupData(
          [newFailureWithAnnotation({snoozeTime: Date.now() + 1000 * 1000})]));
      assert.equal(group.category, 'snoozed');
    });

    it('should be "failedOnce" when there is only one failure', function() {
      var failure = newFailureWithAnnotation();
      failure.resultNodesByBuilder = {some_key: {failingBuildCount: 1}}
      var group = new CTFailureGroup('', new CTStepFailureGroupData(
          [failure]));
      assert.equal(group.category, 'failedOnce');
    });

    it('should be "failedOnce" when each failure only failed once', function() {
      var failure = newFailureWithAnnotation();
      failure.resultNodesByBuilder = {some_key: {failingBuildCount: 1}}
      var failure2 = newFailureWithAnnotation();
      failure2.resultNodesByBuilder = {some_key: {failingBuildCount: 1}}
      var group = new CTFailureGroup('', new CTStepFailureGroupData(
          [failure, failure2]));
      assert.equal(group.category, 'failedOnce');
    });

    it('should not be "failedOnce" when there is more than one failure', function() {
      var failure = newFailureWithAnnotation();
      failure.resultNodesByBuilder = {some_key: {failingBuildCount: 1},
                                      other_key: {failingBuildCount: 1}}
      var group = new CTFailureGroup('', new CTStepFailureGroupData(
          [failure]));
      assert.equal(group.category, 'default');
    });

    it('treeCloser should win over failedOnce', function() {
      var failure = newFailureWithAnnotation();
      failure.resultNodesByBuilder = {some_key: {failingBuildCount: 1, isTreeCloser: true}}
      var group = new CTFailureGroup('', new CTStepFailureGroupData(
          [failure]));
      assert.equal(group.category, 'treeCloser');
    });

    it('snoozed should win over treeCloser', function() {
      var failure = newFailureWithAnnotation({snoozeTime: Date.now() + 1000 * 1000}, true);
      var group = new CTFailureGroup('', new CTStepFailureGroupData(
          [failure]));
      assert.equal(group.category, 'snoozed');
    });
  });

  describe('snooze', function() {
    it('should set isSnoozed', function(done) {
      var group = new CTFailureGroup('', new CTStepFailureGroupData([newFailureWithAnnotation()]));
      group.snoozeUntil(Date.now() + 1000 * 1000).then(function() {
        assert.isTrue(group.isSnoozed);
        done();
      });
    });
  });

  describe('unsnooze', function() {
    it('should clear isSnoozed', function(done) {
      var group = new CTFailureGroup('', new CTStepFailureGroupData([newFailureWithAnnotation()]));
      group.snoozeUntil(Date.now() + 1000 * 1000).then(function() {
        group.unsnooze().then(function() {
          assert.isFalse(group.isSnoozed);
          done();
        });
      });
    });
  });

  describe('setBug', function() {
    it('should store the bug', function(done) {
      var group = new CTFailureGroup('', new CTStepFailureGroupData([newFailureWithAnnotation()]));
      group.setBug('123').then(function() {
        assert.equal(group.bug, 'https://crbug.com/123');
        assert.equal(group._annotation.bug, 'https://crbug.com/123');
        assert.equal(group.bugLabel, 'Bug 123');
        done();
      });
    });

    it('should support URLs', function(done) {
      var group = new CTFailureGroup('', new CTStepFailureGroupData([newFailureWithAnnotation()]));
      group.setBug('https://foobar.com/?id=876&x=y').then(function() {
        assert.equal(group.bug, 'https://foobar.com/?id=876&x=y');
        assert.equal(group._annotation.bug, 'https://foobar.com/?id=876&x=y');
        assert.equal(group.bugLabel, 'Bug 876');
        done();
      });
    });
  });

  describe('clearBug', function() {
    it('should work', function(done) {
      var group = new CTFailureGroup('', new CTStepFailureGroupData([]));
      group.setBug('123').then(function() {
        group.clearBug().then(function() {
          assert.isUndefined(group.bug);
          assert.isUndefined(group.bugLabel);
          assert.notProperty(group._annotation, 'bug');
          done();
        });
      });
    });
  });

  describe('annotations', function() {
    it('should have sensible defaults', function() {
      var group = new CTFailureGroup('', new CTStepFailureGroupData([]));
      assert.deepEqual(group._annotation, {});
      assert.isFalse(group.isSnoozed);
      assert.isUndefined(group.bug);
      assert.isUndefined(group.bugLabel);
    });

    it('should compute properties', function() {
      var group = new CTFailureGroup('', new CTStepFailureGroupData([newFailureWithAnnotation(
          {snoozeTime: Date.now() + 1000 * 1000, bug: 'https://crbug.com/123'})]));
      assert.isTrue(group.isSnoozed);
      assert.equal(group.bug, 'https://crbug.com/123');
    });

    it('should ignore snoozeTime unless it is present on all alerts', function() {
      var notSnoozedMultipleAlerts = new CTFailureGroup('', new CTStepFailureGroupData([
        new CTStepFailure('step', 'reason', [
          {key: 'a', annotation: {snoozeTime: Date.now() + 1000 * 1000}},
          {key: 'b',},
        ])
      ]));
      var notSnoozedMultipleFailures = new CTFailureGroup('', new CTStepFailureGroupData([
        new CTStepFailure('step', 'reason', [
          {key: 'a', annotation: {snoozeTime: Date.now() + 1000 * 1000}},
        ]),
        new CTStepFailure('step', 'reason', [
          {key: 'b'},
        ]),
      ]));
      var snoozedMultipleAlerts = new CTFailureGroup('', new CTStepFailureGroupData([
        new CTStepFailure('step', 'reason', [
          {key: 'a', annotation: {snoozeTime: Date.now() + 1000 * 1000}},
          {key: 'b', annotation: {snoozeTime: Date.now() + 1000 * 1000}},
        ])
      ]));
      var snoozedMultipleFailures = new CTFailureGroup('', new CTStepFailureGroupData([
        new CTStepFailure('step', 'reason', [
          {key: 'a', annotation: {snoozeTime: Date.now() + 1000 * 1000}},
        ]),
        new CTStepFailure('step', 'reason', [
          {key: 'b', annotation: {snoozeTime: Date.now() + 1000 * 1000}},
        ]),
      ]));
      assert.isFalse(notSnoozedMultipleAlerts.isSnoozed);
      assert.isFalse(notSnoozedMultipleFailures.isSnoozed);
      assert.isTrue(snoozedMultipleAlerts.isSnoozed);
      assert.isTrue(snoozedMultipleFailures.isSnoozed);
    });

    it('should use the earliest snoozeTime of all alerts', function() {
      var timeFuture = Date.now() + 1000 * 1000;
      var timePast = Date.now() - 1000 * 1000;

      var notSnoozed = new CTFailureGroup('', new CTStepFailureGroupData([
        new CTStepFailure('step', 'reason', [
          {key: 'a', annotation: {snoozeTime: timeFuture}},
          {key: 'b', annotation: {snoozeTime: timePast}},
        ])
      ]));

      assert.isFalse(notSnoozed.isSnoozed);
    });

    it('should be persisted', function(done) {
      var group = new CTFailureGroup('', new CTStepFailureGroupData(
          [newFailureWithAnnotation(), newFailureWithAnnotation()]));
      group.snoozeUntil(123).then(function() {
        group.setBug('456').then(function() {
          CTFailureGroup.fetchAnnotations().then(function(annotations) {
            assert.deepEqual(annotations[group.data.failures[0].keys()[0]], {snoozeTime: 123, bug: 'https://crbug.com/456'});
            assert.deepEqual(annotations[group.data.failures[1].keys()[0]], {snoozeTime: 123, bug: 'https://crbug.com/456'});
            done();
          });
        });
      });
    });
  });
});

})()
</script>
